using System.Collections.Generic;

namespace Sustainalytics.ESGRatings.BusinessLogic.Computing
{
    public interface IIndex<TU, in TV>
    {
        /// <summary>
        /// Gets number of keys
        /// </summary>
        int Count { get; }

        /// <summary>
        /// If items are sorted by a selector
        /// this property returns the index of items marked as heads of segments
        /// </summary>
        int[] GroupByHeads { get; }


        /// <summary>
        /// Returns the number of distinct selection items used to group items
        /// </summary>
        int SelectorsCount { get; }

        /// <summary>
        /// Gets the elements in group
        /// </summary>
        /// <param name="itemKey">Reference element</param>
        /// <returns>A set of elements in the same group</returns>
        IEnumerable<TU> GetGroupElements(TU itemKey);


        /// <summary>
        /// Get the elements in a group
        /// </summary>
        /// <typeparam name="TV">Type of the selector</typeparam>
        /// <param name="itemSelector">Set of selectors that each denote a group</param>
        /// <returns>Elements that are part of the same group as the given keys</returns>
        IEnumerable<TU> GetGroupElements(IEnumerable<TV> itemSelector);



        /// <summary>
        /// Given a key gets the index in the inner collection
        /// </summary>
        /// <param name="key">Type of key</param>
        /// <returns>Integer index of key</returns>
        int GetIndex(TU key);


        /// <summary>
        /// Given a selector gets the indexes of the items that have attached this selector
        /// </summary>
        /// <param name="p">Selector</param>
        /// <returns>An array of indexis</returns>
        int[] GetIndex(object p);


       


        ///// <summary>
        ///// Given a selectors sets gets the indexes of the items that have attached a selector
        ///// </summary>
        ///// <typeparam name="TV"></typeparam>
        ///// <param name="itemSelector"></param>
        ///// <returns></returns>
        //int[] GetIndexis<TV>(IEnumerable<TV> itemSelector);


        /// <summary>
        /// Given the index of an item returns the key of item
        /// </summary>
        /// <param name="index">Index</param>
        /// <returns>The key of the item</returns>
        TU GetItem(int index);

        /// <summary>
        /// Gets all the items in the indexing structure
        /// </summary>
        /// <returns>An array of keys</returns>
        TU[] GetReverseIndexCopy();


        /// <summary>
        /// Given an items' selector, get the group index that the item has associated
        /// </summary>
        /// <typeparam name="TV">Type of selector</typeparam>
        /// <param name="itemSelector">Selector</param>
        /// <returns>Index of group</returns>
        int GetGroupId(TV itemSelector);

        
    }
}